<template>
  <slot></slot>
</template>
<script lang="ts">
import type { ComponentPublicInstance } from 'vue'
import type { Instance as TippyInstance, Placement as TippyPlacement } from 'tippy.js'
import tippy from 'tippy.js'

function cast<T>(o: any): T {
  return o as unknown as T
}

type WithTippy = ComponentPublicInstance & {
  $tippy: TippyInstance | null
}

export default {
  props: {
    trigger: {
      type: String,
      default: 'mouseenter focus'
    },
    placement: {
      type: String,
      default: 'top'
    },
    content: {
      type: String
    },
    theme: {
      type: String,
      default: 'light-border'
    }
  },
  watch: {
    content(v) {
      cast<WithTippy>(this).$tippy?.setContent(v)
    }
  },
  mounted() {
    this.initTippy()
  },
  unmounted() {
    this.destroyTippy()
  },
  methods: {
    initTippy() {
      const el = (this.$el as Element)?.nextElementSibling
      if (el) {
        const opts = {
          content: this.content,
          trigger: this.trigger,
          placement: this.placement as TippyPlacement,
          theme: this.theme
        }
        const tp = tippy(el, opts)
        cast<WithTippy>(this).$tippy = tp
      }
    },
    destroyTippy() {
      const w = cast<WithTippy>(this)
      const tp = w?.$tippy
      if (tp) {
        tp.destroy()
        w.$tippy = null
      }
    }
  }
}
</script>
